home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / tweak16b.zip / VGALIB.CPP < prev    next >
C/C++ Source or Header  |  1993-11-22  |  7KB  |  387 lines

  1. #include <dos.h>
  2. #include <conio.h>
  3. #include <string.h>
  4.  
  5. #include "misc.hpp"
  6. #include "screen.hpp"
  7. #include "vgalib.hpp"
  8.  
  9.  
  10. GraphicsAPI::GraphicsAPI(int xr, int yr, int vxr, int vyr, int clrs)
  11.     {
  12.     int segm, offs;
  13.     xres = xr;
  14.     yres = yr;
  15.     vxres = vxr;
  16.     vyres = vyr;
  17.     colors = clrs;
  18.     libID = "Generic Graphics";
  19.     asm    {
  20.         push    bp
  21.         mov        ax, 1130h
  22.         mov        bh, 03h
  23.         int        10h
  24.         mov        ax, bp
  25.         pop        bp
  26.         mov        [segm], es
  27.         mov        [offs], ax
  28.         }
  29.     font = (unsigned char *)MK_FP(segm, offs);
  30.     fontHeight = fontWidth = 8;
  31.     }
  32.  
  33. void GraphicsAPI::hLine(int x, int y, int l)
  34.     {
  35.     while (l--)
  36.         putPixel(x++, y);
  37.     }
  38.  
  39. void GraphicsAPI::vLine(int x, int y, int l)
  40.     {
  41.     while (l--)
  42.         putPixel(x, y++);
  43.     }
  44.  
  45. /*
  46.  *    Generic line drawing routine, using Bresenham's algorithm.
  47.  *    Taken from Richard Wilton: "PC & PS/2 Video Systems" p. 166-7
  48.  */
  49.  
  50. void GraphicsAPI::line(int x1, int y1, int x2, int y2)
  51.     {
  52.     if (x1==x2)
  53.         {
  54.         sort(y1, y2);
  55.         vLine(x1, y1, y2-y1+1);
  56.         return;
  57.         }
  58.     if (y1==y2)
  59.         {
  60.         sort(x1, x2);
  61.         hLine(x1, y1, x2-x1+1);
  62.         }
  63.     int dx = absolute(x2-x1);
  64.     int dy = absolute(y2-y1);
  65.     if (dx >= dy)
  66.         {
  67.         if (x1>x2)
  68.             {
  69.             swap(x1, x2);
  70.             swap(y1, y2);
  71.             }
  72.         int yincr = 1;
  73.         if (y2<y1)
  74.             yincr = -yincr;
  75.         int d = 2 * dy - dx;
  76.         int aincr = 2 * (dy - dx);
  77.         int bincr = 2 * dy;
  78.         int x = x1;
  79.         int y = y1;
  80.         putPixel(x, y);
  81.         while (++x <= x2)
  82.             {
  83.             if (d >= 0)
  84.                 {
  85.                 y += yincr;
  86.                 d += aincr;
  87.                 }
  88.             else
  89.                 d += bincr;
  90.             putPixel(x, y);
  91.             }
  92.         }
  93.     else
  94.         {
  95.         if (y1>y2)
  96.             {
  97.             swap(x1, x2);
  98.             swap(y1, y2);
  99.             }                           
  100.         int xincr = 1;
  101.         if (x2<x1)
  102.             xincr = -xincr;
  103.         int d = 2*dx - dy;
  104.         int aincr = 2 * (dx - dy);
  105.         int bincr = 2 * dx;
  106.         int x = x1;
  107.         int y = y1;
  108.         putPixel(x, y);
  109.         while (++y <= y2)
  110.             {
  111.             if (d >= 0)
  112.                 {
  113.                 x += xincr;
  114.                 d += aincr;
  115.                 }
  116.             else
  117.                 d += bincr;
  118.             putPixel(x, y);
  119.             }
  120.         }
  121.     }
  122.  
  123. void GraphicsAPI::rectangle(int x1, int y1, int x2, int y2)
  124.     {
  125.     sort(x1, x2);
  126.     sort(y1, y2);
  127.     hLine(x1, y1, x2-x1);
  128.     hLine(x1, y2, x2-x1);
  129.     vLine(x1, y1, y2-y1);
  130.     vLine(x2, y1, y2-y1);
  131.     }
  132.  
  133. void GraphicsAPI::bar(int x1, int y1, int x2, int y2)
  134.     {
  135.     int width = x2-x1+1;
  136.     for (int y = y1; y < y2; ++y)
  137.         hLine(x1, y, width);
  138.     }
  139.  
  140. void GraphicsAPI::wipe()
  141.     {
  142.     bar(0, 0, vxres, vyres);
  143.     }
  144.  
  145. void GraphicsAPI::putChar(int x, int y, int ch)
  146.     {
  147.     unsigned char *fptr = font + fontHeight*ch;
  148.     for (int j=0; j<fontHeight; ++j, ++fptr)
  149.         {
  150.         char mask = *fptr;
  151.         for (int i=0; i<fontWidth; ++i)
  152.             {
  153.             asm shl        [mask], 1;
  154.             asm jnc        skip
  155.                 putPixel(x+i, y+j, color);
  156.             skip:
  157.             }
  158.         }
  159.     }
  160.  
  161. void GraphicsAPI::putText(int x, int y, char *txt)
  162.     {
  163.     switch (hJustify)
  164.         {
  165.         case HCENTER:
  166.             x -= fontWidth * strlen(txt) / 2;
  167.             break;
  168.         case RIGHT:
  169.             x -= fontWidth * strlen(txt);
  170.             break;
  171.         }
  172.     switch (vJustify)
  173.         {
  174.         case VCENTER:
  175.             y -= fontHeight / 2;
  176.             break;
  177.         case BOTTOM:
  178.             y -= fontHeight;
  179.             break;
  180.         }
  181.  
  182.     while (*txt)
  183.         {
  184.         putChar(x, y, *(txt++));
  185.         x += fontWidth;
  186.         }
  187.     }
  188.  
  189. void GraphicsAPI::setTextJustify(HJustify h, VJustify v)
  190.     {
  191.     hJustify = h;
  192.     vJustify = v;
  193.     }
  194.  
  195.  
  196. /*
  197.  *    VGAGraphicsAPI
  198.  */
  199.  
  200. unsigned char *VGAGraphicsAPI::videoBuf =
  201.     (unsigned char *)MK_FP(0xa000,0);
  202.  
  203. VGAGraphicsAPI::VGAGraphicsAPI(int xr, int yr, int vxr, int xb, int clrs)
  204.     : GraphicsAPI(xr, yr, vxr, 65536L/xb, clrs), xbytes(xb)
  205.     {
  206.     libID = "VGA Graphics";
  207.     outp(0x3ce, 0x05);
  208.     int t = inp(0x3cf);
  209.     outpw(0x3ce, 0x05 | (t & 0xfc) << 8);    // write mode 0
  210.     outpw(0x3c4, 0x0f02);                    // enable all planes
  211.     }
  212.  
  213.  
  214. void VGAGraphicsAPI::syncWithRefresh()
  215.     {
  216.     while (inp(0x3da)&0x8);
  217.     while (!(inp(0x3da)&0x8));
  218.     }
  219.  
  220. unsigned VGAGraphicsAPI::getOffset(int x, int y)
  221.     {
  222.     return y * xbytes + x/(vxres/xbytes);
  223.     }
  224.  
  225. void VGAGraphicsAPI::setBase(int x=0, int y=0)
  226.     {
  227.     unsigned offset = getOffset(x,y);
  228.     inp(0x3da);
  229.     outp(0x3c0, 0x33);
  230.     outp(0x3c0, getPelPan(x));
  231.     outpw(0x3d4, 0x0c | (offset & 0xff00));
  232.     outpw(0x3d4, 0x0d | (offset & 0x00ff)<<8);
  233.     syncWithRefresh();
  234.     }
  235.  
  236.  
  237. /*
  238.  *    Planar16
  239.  */
  240.  
  241. Planar16::Planar16(int xr, int yr, int vxr)
  242.     : VGAGraphicsAPI(xr, yr, vxr, vxr>>3, 16)
  243.     {
  244.     libID = "4-plane 16-color mode";
  245.     outpw(0x3ce, 0x0f01);                    // enable set/reset
  246.     }
  247.  
  248. void Planar16::putPixel(int x, int y, int c)
  249.     {
  250.     outpw(0x3ce, 0x00 | (c<<8));        // set/reset to select color
  251.     outpw(0x3ce, 0x08 | 0x8000>>(x&7));    // bit mask to select bit
  252.     unsigned char *pos = graphScr+y*xbytes+(x>>3);
  253.     *pos = *pos;
  254.     }
  255.  
  256. int Planar16::getPixel(int x, int y)
  257.     {
  258.     return videoBuf[y*xbytes+x];
  259.     }
  260.  
  261. void Planar16::hLine(int x, int y, int l)
  262.     {
  263.     outpw(0x3ce, 0x00 | (color<<8));    // set/reset to select color
  264.     unsigned char *pos = graphScr+y*xbytes+(x>>3);
  265.     int mask;
  266.     int shift = x & 7;
  267.     if (shift > 0)
  268.         {
  269.         mask = 0x00ff >> shift;
  270.         l -= 8 - shift;
  271.         if (l<0)
  272.             mask &= 0xff << -l;
  273.         outpw(0x3ce, 0x08 | mask << 8);    // bit mask to select first bits
  274.         *pos = *pos;
  275.         ++pos;
  276.         }
  277.     if (l >= 8)
  278.         {
  279.         outpw(0x3ce, 0xff08);            // bit mask to select 8 bits
  280.         memset(pos, 0, l>>3);
  281.         pos += l>>3;
  282.         l -= l & 0xf8;
  283.         }
  284.     if (l >= 0)
  285.         {
  286.         mask = 0xff00 << (8-l);
  287.         outpw(0x3ce, 0x08 | mask);        // bit mask to select last bits
  288.         *pos = *pos;
  289.         }
  290.     }
  291.  
  292. int Planar16::getPelPan(int x)
  293.     {
  294.     return x & 7;
  295.     }
  296.  
  297. /*
  298.  *    Chained256
  299.  */
  300.  
  301. Chained256::Chained256(int xr, int yr, int vxr)
  302.     : VGAGraphicsAPI(xr, yr, vxr, vxr, 256)
  303.     {
  304.     libID = "Chained 256-color mode";
  305.     }
  306.  
  307. void Chained256::putPixel(int x, int y, int c)
  308.     {
  309.     videoBuf[y*xbytes+x] = c;
  310.     }
  311.  
  312. int Chained256::getPixel(int x, int y)
  313.     {
  314.     return videoBuf[y*xbytes+x];
  315.     }
  316.  
  317. void Chained256::hLine(int x, int y, int l)
  318.     {
  319.     memset(graphScr+y*xbytes+x, color, l);
  320.     }
  321.  
  322. unsigned Chained256::getOffset(int x, int y)
  323.     {
  324.     return (y * xbytes + x/(vxres/xbytes)) >> 2; 
  325.     }
  326.  
  327. int Chained256::getPelPan(int x)
  328.     {
  329.     return 2*(x & 3);
  330.     }
  331.  
  332.  
  333. /*
  334.  *    Unchained256
  335.  */
  336.  
  337. Unchained256::Unchained256(int xr, int yr, int vxr)
  338.     : VGAGraphicsAPI(xr, yr, vxr, vxr>>2, 256)
  339.     {
  340.     libID = "Unchained 256-color mode";
  341.     }
  342.  
  343. void Unchained256::putPixel(int x, int y, int c)
  344.     {
  345.     outpw(0x3c4, 0x02 | 0x0100<<(x&3));
  346.     videoBuf[y*xbytes+(x>>2)] = c;
  347.     }
  348.  
  349. int Unchained256::getPixel(int x, int y)
  350.     {
  351.     return videoBuf[y*xbytes+x];
  352.     }
  353.  
  354. void Unchained256::hLine(int x, int y, int l)
  355.     {
  356.     unsigned char *pos = graphScr+y*xbytes+(x>>2);
  357.     int mask;
  358.     int shift = x & 3;
  359.     if (shift > 0)
  360.         {
  361.         mask = 0x000f << shift & 0x000f;
  362.         l -= 4-shift;
  363.         if (l<0)
  364.             mask &= 0x0f >> -l;
  365.         outpw(0x3c4, 0x02 | mask << 8);    // write enable first pixels
  366.         *(pos++) = color;
  367.         }
  368.     if (l >= 4)
  369.         {
  370.         outpw(0x3c4, 0x0f02);            // write enable 4 pixels
  371.         memset(pos, color, l>>2);
  372.         pos += l>>2;
  373.         l -= l & 0xfc;
  374.         }
  375.     if (l >= 0)
  376.         {
  377.         mask = 0x0f00 >> (4-l) & 0x0f00;
  378.         outpw(0x3c4, 0x02 | mask);        // write enable last pixels
  379.         *pos = color;
  380.         }
  381.     }
  382.  
  383. int Unchained256::getPelPan(int x)
  384.     {
  385.     return 2*(x & 3);
  386.     }
  387.